package com.ecr.hub.database.dao.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ecr.hub.database.DaoCopyException;
import com.ecr.hub.database.dao.IDaoInputData;
import com.ecr.hub.database.mapper.MapperInputData;
import com.ecr.hub.model.HubInputData;
import com.ecr.hub.model.enumeration.HubDataInputStatus;

@Repository("daoInputData")
public class DaoInputDataImpl extends MapperInputData implements IDaoInputData {

	private static final String REQ_SELECT_ALL_INPUT_DATA = "SELECT * FROM hub_input_data as input_data ORDER BY id DESC";
	private static final String REQ_SELECT_INPUT_DATA_BY_ID = "SELECT * FROM hub_input_data as input_data WHERE id=?";
	private static final String REQ_INSERT_INPUT_DATA = "INSERT INTO hub_input_data (status,date_processing,file_name_attached,file_name_store) VALUES (?,?,?,?)";
	private static final String REQ_SELECT_LAST_ID_INPUT_DATA = "SELECT LAST_INSERT_ID() FROM hub_input_data LIMIT 1";
	private static final String REQ_UPDATE_INPUT_DATA = "UPDATE hub_input_data SET status=?, date_processing=?, file_name_attached=?, file_name_store=?, error_msg=? WHERE id=?";
	private static final String REQ_DELETE_INPUT_DATA = "DELETE hub_input_data FROM hub_input_data WHERE id=?";
	private static final String REQ_SELECT_ALL_INPUT_DATA_BY_STATUS = "SELECT * FROM hub_input_data as input_data WHERE input_data.status=?";

	// Historisation de la table hub_input_data (1/2).
	private static final String REQ_HISTO_INPUT_DATA = "INSERT INTO hub_histo_input_data VALUES (?,?,?,?,?,?)";
	// Historisation de la table hub_input_data (2/2).
	private static final String REQ_HISTO_INPUT_DATA_DEL = "DELETE FROM hub_input_data WHERE id=?";

	protected final static transient Logger log = LoggerFactory
			.getLogger(DaoInputDataImpl.class);

	@Autowired
	JdbcTemplate jdbcTemplate;

	@Override
	public List<HubInputData> getListAll() throws DataAccessException {

		List<HubInputData> Datas = jdbcTemplate.query(
				REQ_SELECT_ALL_INPUT_DATA, mapperDataInput);
		return Datas;
	}

	@Override
	@Transactional
	public void insert(HubInputData inputData) throws DataAccessException {

		jdbcTemplate
				.update(REQ_INSERT_INPUT_DATA,
						new Object[] { inputData.getStatus().name(),
								inputData.getDateProcessing(),
								inputData.getFileAttachedName(),
								inputData.getFileStoreName() });

		int idInputData = jdbcTemplate
				.queryForInt(REQ_SELECT_LAST_ID_INPUT_DATA);

		// mise à jour de l'id
		inputData.setId(idInputData);
	}

	@Override
	@Transactional
	public void update(HubInputData inputData) throws DataAccessException {

		Object[] queryParams = { inputData.getStatus().name(),
				inputData.getDateProcessing(), inputData.getFileAttachedName(),
				inputData.getFileStoreName(), inputData.getErrorMessage(),
				inputData.getId() };

		jdbcTemplate.update(REQ_UPDATE_INPUT_DATA, queryParams);

	}

	@Override
	public List<HubInputData> findByStatus(HubDataInputStatus status) {

		List<HubInputData> listInputData = null;
		listInputData = jdbcTemplate.query(REQ_SELECT_ALL_INPUT_DATA_BY_STATUS,
				new Object[] { status.name() }, mapperDataInput);
		return listInputData;
	}

	@Override
	public void delete(HubInputData inputData) throws DataAccessException {

		jdbcTemplate.update(REQ_DELETE_INPUT_DATA,
				new Object[] { inputData.getId() });
	}

	@Override
	public HubInputData findById(int id) throws DataAccessException {

		HubInputData hubInputData = jdbcTemplate.queryForObject(
				REQ_SELECT_INPUT_DATA_BY_ID, new Object[] { id },
				mapperDataInput);

		return hubInputData;
	}

	/**
	 * Comme il y a peu de champs à effacer (-10 enregistrement par run
	 * (estimation)), on fait la selection et on se contente de boucler, on
	 * déplace l'enregistrement et on supprime la ligne dans la table
	 * hub_traffic. On vérifie que le transfert est bien effectué à l'aide des
	 * deux entiers.
	 */
	@Override
	@Transactional
	public List<HubInputData> historize() throws DataAccessException {

		List<HubInputData> lstInputData = jdbcTemplate.query(
				REQ_SELECT_ALL_INPUT_DATA_BY_STATUS,
				new Object[] { HubDataInputStatus.CLOSE.getValue() },
				mapperDataInput);

		for (HubInputData inputData : lstInputData) {

			// Comme il y a peu de champs, on fait directement l'insert.
			int nbUpdate = jdbcTemplate.update(
					REQ_HISTO_INPUT_DATA,
					new Object[] { inputData.getId(),
							inputData.getStatus().name(),
							inputData.getDateProcessing(),
							inputData.getFileAttachedName(),
							inputData.getFileStoreName(),
							inputData.getErrorMessage() });

			int nb_delete = jdbcTemplate.update(REQ_HISTO_INPUT_DATA_DEL,
					new Object[] { inputData.getId() });

			if (nbUpdate == 0 || nb_delete == 0)
				throw new DaoCopyException(
						"Hub : Impossible de transférer la ligne : "
								+ inputData.getId()
								+ " dans la table d'historique.");
		}
		return lstInputData;
	}
}